/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Persistencia;

import Persistencia.exceptions.NonexistentEntityException;
import Persistencia.exceptions.PreexistingEntityException;
import java.io.Serializable;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import motoressa.Sucursal;
import motoressa.Turno;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.transaction.UserTransaction;
import motoressa.Taller;
import motoressa.Tecnico;

/**
 *
 * @author HP
 */
public class TallerJpaController implements Serializable {

    public TallerJpaController(UserTransaction utx, EntityManagerFactory emf) {
        this.utx = utx;
        this.emf = emf;
    }
    private UserTransaction utx = null;
    private EntityManagerFactory emf = null;

    public TallerJpaController() {
        emf=Persistence.createEntityManagerFactory("MotoresSAPU");
    }
    

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(Taller taller) throws PreexistingEntityException, Exception {
        if (taller.getMisTurnos() == null) {
            taller.setMisTurnos(new ArrayList<Turno>());
        }
        if (taller.getMisTecnicos() == null) {
            taller.setMisTecnicos(new ArrayList<Tecnico>());
        }
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Sucursal miSucursal = taller.getMiSucursal();
            if (miSucursal != null) {
                miSucursal = em.getReference(miSucursal.getClass(), miSucursal.getCodigo());
                taller.setMiSucursal(miSucursal);
            }
            List<Turno> attachedMisTurnos = new ArrayList<Turno>();
            for (Turno misTurnosTurnoToAttach : taller.getMisTurnos()) {
                misTurnosTurnoToAttach = em.merge(misTurnosTurnoToAttach);
                attachedMisTurnos.add(misTurnosTurnoToAttach);
            }
            taller.setMisTurnos(attachedMisTurnos);
            List<Tecnico> attachedMisTecnicos = new ArrayList<Tecnico>();
            for (Tecnico misTecnicosTecnicoToAttach : taller.getMisTecnicos()) {
                misTecnicosTecnicoToAttach = em.getReference(misTecnicosTecnicoToAttach.getClass(), misTecnicosTecnicoToAttach.getDni());
                attachedMisTecnicos.add(misTecnicosTecnicoToAttach);
            }
            taller.setMisTecnicos(attachedMisTecnicos);
            em.persist(taller);
            if (miSucursal != null) {
                miSucursal.getMisTalleres().add(taller);
                miSucursal = em.merge(miSucursal);
            }
            for (Turno misTurnosTurno : taller.getMisTurnos()) {
                Taller oldMiTallerOfMisTurnosTurno = misTurnosTurno.getMiTaller();
                misTurnosTurno.setMiTaller(taller);
                misTurnosTurno = em.merge(misTurnosTurno);
                if (oldMiTallerOfMisTurnosTurno != null) {
                    oldMiTallerOfMisTurnosTurno.getMisTurnos().remove(misTurnosTurno);
                    oldMiTallerOfMisTurnosTurno = em.merge(oldMiTallerOfMisTurnosTurno);
                }
            }
            for (Tecnico misTecnicosTecnico : taller.getMisTecnicos()) {
                Taller oldMiTallerOfMisTecnicosTecnico = misTecnicosTecnico.getMiTaller();
                misTecnicosTecnico.setMiTaller(taller);
                misTecnicosTecnico = em.merge(misTecnicosTecnico);
                if (oldMiTallerOfMisTecnicosTecnico != null) {
                    oldMiTallerOfMisTecnicosTecnico.getMisTecnicos().remove(misTecnicosTecnico);
                    oldMiTallerOfMisTecnicosTecnico = em.merge(oldMiTallerOfMisTecnicosTecnico);
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            if (findTaller(taller.getCodigo()) != null) {
                throw new PreexistingEntityException("Taller " + taller + " already exists.", ex);
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(Taller taller) throws NonexistentEntityException, Exception {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Taller persistentTaller = em.find(Taller.class, taller.getCodigo());
            Sucursal miSucursalOld = persistentTaller.getMiSucursal();
            Sucursal miSucursalNew = taller.getMiSucursal();
            List<Turno> misTurnosOld = persistentTaller.getMisTurnos();
            List<Turno> misTurnosNew = taller.getMisTurnos();
            List<Tecnico> misTecnicosOld = persistentTaller.getMisTecnicos();
            List<Tecnico> misTecnicosNew = taller.getMisTecnicos();
            if (miSucursalNew != null) {
                miSucursalNew = em.getReference(miSucursalNew.getClass(), miSucursalNew.getCodigo());
                taller.setMiSucursal(miSucursalNew);
            }
            List<Turno> attachedMisTurnosNew = new ArrayList<Turno>();
            for (Turno misTurnosNewTurnoToAttach : misTurnosNew) {
                misTurnosNewTurnoToAttach = em.merge(misTurnosNewTurnoToAttach);
                attachedMisTurnosNew.add(misTurnosNewTurnoToAttach);
            }
            misTurnosNew = attachedMisTurnosNew;
            taller.setMisTurnos(misTurnosNew);
            List<Tecnico> attachedMisTecnicosNew = new ArrayList<Tecnico>();
            for (Tecnico misTecnicosNewTecnicoToAttach : misTecnicosNew) {
                misTecnicosNewTecnicoToAttach = em.getReference(misTecnicosNewTecnicoToAttach.getClass(), misTecnicosNewTecnicoToAttach.getDni());
                attachedMisTecnicosNew.add(misTecnicosNewTecnicoToAttach);
            }
            misTecnicosNew = attachedMisTecnicosNew;
            taller.setMisTecnicos(misTecnicosNew);
            taller = em.merge(taller);
            if (miSucursalOld != null && !miSucursalOld.equals(miSucursalNew)) {
                miSucursalOld.getMisTalleres().remove(taller);
                miSucursalOld = em.merge(miSucursalOld);
            }
            if (miSucursalNew != null && !miSucursalNew.equals(miSucursalOld)) {
                miSucursalNew.getMisTalleres().add(taller);
                miSucursalNew = em.merge(miSucursalNew);
            }
            for (Turno misTurnosOldTurno : misTurnosOld) {
                if (!misTurnosNew.contains(misTurnosOldTurno)) {
                    misTurnosOldTurno.setMiTaller(null);
                    misTurnosOldTurno = em.merge(misTurnosOldTurno);
                }
            }
            for (Turno misTurnosNewTurno : misTurnosNew) {
                if (!misTurnosOld.contains(misTurnosNewTurno)) {
                    Taller oldMiTallerOfMisTurnosNewTurno = misTurnosNewTurno.getMiTaller();
                    misTurnosNewTurno.setMiTaller(taller);
                    misTurnosNewTurno = em.merge(misTurnosNewTurno);
                    if (oldMiTallerOfMisTurnosNewTurno != null && !oldMiTallerOfMisTurnosNewTurno.equals(taller)) {
                        oldMiTallerOfMisTurnosNewTurno.getMisTurnos().remove(misTurnosNewTurno);
                        oldMiTallerOfMisTurnosNewTurno = em.merge(oldMiTallerOfMisTurnosNewTurno);
                    }
                }
            }
            for (Tecnico misTecnicosOldTecnico : misTecnicosOld) {
                if (!misTecnicosNew.contains(misTecnicosOldTecnico)) {
                    misTecnicosOldTecnico.setMiTaller(null);
                    misTecnicosOldTecnico = em.merge(misTecnicosOldTecnico);
                }
            }
            for (Tecnico misTecnicosNewTecnico : misTecnicosNew) {
                if (!misTecnicosOld.contains(misTecnicosNewTecnico)) {
                    Taller oldMiTallerOfMisTecnicosNewTecnico = misTecnicosNewTecnico.getMiTaller();
                    misTecnicosNewTecnico.setMiTaller(taller);
                    misTecnicosNewTecnico = em.merge(misTecnicosNewTecnico);
                    if (oldMiTallerOfMisTecnicosNewTecnico != null && !oldMiTallerOfMisTecnicosNewTecnico.equals(taller)) {
                        oldMiTallerOfMisTecnicosNewTecnico.getMisTecnicos().remove(misTecnicosNewTecnico);
                        oldMiTallerOfMisTecnicosNewTecnico = em.merge(oldMiTallerOfMisTecnicosNewTecnico);
                    }
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                int id = taller.getCodigo();
                if (findTaller(id) == null) {
                    throw new NonexistentEntityException("The taller with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(int id) throws NonexistentEntityException {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Taller taller;
            try {
                taller = em.getReference(Taller.class, id);
                taller.getCodigo();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The taller with id " + id + " no longer exists.", enfe);
            }
            Sucursal miSucursal = taller.getMiSucursal();
            if (miSucursal != null) {
                miSucursal.getMisTalleres().remove(taller);
                miSucursal = em.merge(miSucursal);
            }
            List<Turno> misTurnos = taller.getMisTurnos();
            for (Turno misTurnosTurno : misTurnos) {
                misTurnosTurno.setMiTaller(null);
                misTurnosTurno = em.merge(misTurnosTurno);
            }
            List<Tecnico> misTecnicos = taller.getMisTecnicos();
            for (Tecnico misTecnicosTecnico : misTecnicos) {
                misTecnicosTecnico.setMiTaller(null);
                misTecnicosTecnico = em.merge(misTecnicosTecnico);
            }
            em.remove(taller);
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<Taller> findTallerEntities() {
        return findTallerEntities(true, -1, -1);
    }

    public List<Taller> findTallerEntities(int maxResults, int firstResult) {
        return findTallerEntities(false, maxResults, firstResult);
    }

    private List<Taller> findTallerEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            Query q = em.createQuery("select object(o) from Taller as o");
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public Taller findTaller(int id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(Taller.class, id);
        } finally {
            em.close();
        }
    }

    public int getTallerCount() {
        EntityManager em = getEntityManager();
        try {
            Query q = em.createQuery("select count(o) from Taller as o");
            return ((Long) q.getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }
    
}
